package com.ytd.smartcanteen.weighting.devices;


import android.media.MediaPlayer;
import android.os.SystemClock;

import com.ytd.common.base.BaseApplication;
import com.ytd.common.util.LogUtil;
import com.ytd.common.util.ThreadUtil;
import com.ytd.smartcanteen.weighting.util.WeightConfig;

import java.io.File;
import java.io.IOException;

import android_serialport_api.SerialCallback;
import android_serialport_api.SerialPort;
import cn.ytd.smartcanteen.weighting.BuildConfig;
import cn.ytd.smartcanteen.weighting.R;

/**
 * Led 管理器
 *
 * @author gaoguanchao
 * @since 2023/3/22 0022
 */
public class LEDManager {
    private static final String TAG = "LEDManager";

    private SerialPort mLEDPort = null;

    private MediaPlayer mWarning;

    boolean isAnomaly;

    private boolean isInit;

    SerialCallback ledCallBack = new SerialCallback() {
        @Override
        public void onReadData(final String data) {
        }
    };

    public void init() {
        try {
            String ledPath = WeightConfig.getLedPath();
            int ledBit = WeightConfig.getLedBit();
            LogUtil.d("LEDManager init " + ledPath + "  " + ledBit);
            mLEDPort = new SerialPort(new File(ledPath), ledBit, ledCallBack);
            mLEDPort.tcflush();
            isInit = true;
            LogUtil.d("LEDManager init success");
        } catch (IOException e) {
            LogUtil.e("LEDManager init Exception", e);
            isInit = false;
        }
    }

    public void LED(Boolean RED, Boolean GREEN, Boolean BLUE) {
        if (!isInit || isAnomaly) {
            return;
        }
        showFlicker = false;
        if (RED && !GREEN && !BLUE) {
            startWarning();
        } else {
            stopWarning();
        }
        showLed(RED, GREEN, BLUE);
    }

    private void showLed(Boolean RED, Boolean GREEN, Boolean BLUE) {
        if (RED) {
            mLEDPort.send("led01ON\r\n".getBytes());
        } else {
            mLEDPort.send("led01OFF\r\n".getBytes());
        }
        if (GREEN) {
            mLEDPort.send("led02ON\r\n".getBytes());
        } else {
            mLEDPort.send("led02OFF\r\n".getBytes());
        }
        if (BLUE) {
            mLEDPort.send("led03ON\r\n".getBytes());
        } else {
            mLEDPort.send("led03OFF\r\n".getBytes());
        }
    }

    public void stopWarning() {
        if (!isInit || isAnomaly) {
            return;
        }
        LogUtil.e("stopWarning:  isAnomaly:" + isAnomaly);
        if (mWarning != null) {
            mWarning.stop();
            mWarning.reset();
            mWarning.release();
            mWarning = null;
        }
    }

    public void setAnomaly(boolean anomaly) {
        isAnomaly = anomaly;
    }

    private void startWarning() {
        if (mWarning != null) {
            mWarning.stop();
            mWarning.reset();
            mWarning.release();
            mWarning = null;
        }
        mWarning = MediaPlayer.create(BaseApplication.getContext(), R.raw.dd);
        if (BuildConfig.DEBUG) {
            mWarning.setVolume(0.2f, 0.2f);
        } else {
            mWarning.setVolume(1f, 1f);
        }
        mWarning.setOnCompletionListener(m2p -> {
            if (mWarning != null) {
                mWarning.start();
            }
        });
        mWarning.start();
        LogUtil.e("startWarning");
    }

    public void release() {
        mLEDPort.closePort();
        if (mWarning != null) {
            mWarning.stop();
            mWarning.reset();
            mWarning.release();
            mWarning = null;
        }
    }

    public void setCloseFlicker(boolean closeFlicker) {
        this.closeFlicker = closeFlicker;
    }

    private boolean closeFlicker = false;
    private volatile boolean showFlicker = false;
    private volatile boolean flickerRunning = false;
    private final Runnable flickerYellowRunnable = new Runnable() {
        @Override
        public void run() {
            flickerRunning = true;
            boolean isOpen = false;
            LogUtil.d("flickerYellowRunnable start");
            for (int i = 0; i < 120; i++) {
                if (closeFlicker) {
                    break;
                }
                if (showFlicker) {
                    if (!isOpen) {
                        showLed(true, true, false);
                    } else {
                        showLed(false, false, false);
                    }
                }
                isOpen = !isOpen;
                SystemClock.sleep(500);
            }
            if (showFlicker) {
                showLed(false, false, false);
            }
            LogUtil.d("flickerYellowRunnable end");
            flickerRunning = false;
        }
    };

    public void flickerYellow() {
        if (isAnomaly || flickerRunning) {
            return;
        }
        closeFlicker = false;
        showFlicker = true;
        ThreadUtil.execute(flickerYellowRunnable);
    }

    private LEDManager() {
    }

    public static LEDManager getInstance() {
        return ManagerHolder.instance;
    }

    public void closeAll() {
        LED(false, false, false);
        showFlicker = true;
    }

    public void showRed() {
        LED(true, false, false);
    }

    public void showBlue() {
        LEDManager.getInstance().LED(false, false, true);
    }

    public void showGreen() {
        LEDManager.getInstance().LED(false, true, false);
    }

    public void showOffline() {
        LEDManager.getInstance().LED(true, true, false);
    }

    public void showViolet() {
        LEDManager.getInstance().LED(true, false, true);
    }

    private static class ManagerHolder {
        private static final LEDManager instance = new LEDManager();
    }
}
